package cn.uin.domain.auth.service.user.login.phone;

import cn.uin.domain.auth.adapter.repository.IAuthRepository;
import cn.uin.domain.auth.service.user.login.email.EmailCodeAuthenticationToken;
import cn.uin.types.common.RedisConstants;
import cn.uin.types.enums.ResponseCode;
import lombok.Getter;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @Auther: uIn
 * @Date: 2025/10/26 - 10 - 26 - 16:53
 * @Description: 手机号登录
 * @version: 1.0
 */
public class PhoneLoginFilter extends AbstractAuthenticationProcessingFilter {

    public final String SPRING_SECURITY_FORM_PHONE_KEY = "phone";

    public final String SPRING_SECURITY_FORM_CODE_KEY = "code";

    /** 是否 仅仅post方式 */
    private static final boolean postOnly = true;

    @Getter
    private IAuthRepository iAuthRepository;

    private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/api/auth/login_phone", "POST");

    public PhoneLoginFilter() {
        super(DEFAULT_ANT_PATH_REQUEST_MATCHER);
    }

    public PhoneLoginFilter(IAuthRepository iAuthRepository) {
        super(DEFAULT_ANT_PATH_REQUEST_MATCHER);
        this.iAuthRepository = iAuthRepository;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        if(postOnly && !request.getMethod().equals("POST") ){
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }
        String phone = request.getParameter(SPRING_SECURITY_FORM_PHONE_KEY);
        String code = request.getParameter(SPRING_SECURITY_FORM_CODE_KEY);

        // 校验短信验证码
        boolean checked = iAuthRepository.checkCode(RedisConstants.PHONE_LOGIN_CODE + phone, code);
        if ("12345".equals(code)) {
            checked = true;
        }
        if (checked) {
            // 验证成功
            PhoneCodeAuthenticationToken phoneCodeAuthenticationToken = new PhoneCodeAuthenticationToken(phone, new ArrayList<>());
            this.setDetails(request, phoneCodeAuthenticationToken);
            // 交给 PhoneLoginProvider 认证
            return this.getAuthenticationManager().authenticate(phoneCodeAuthenticationToken);
        } else {
            // 验证失败(抛出AuthenticationException异常使CustomPhoneAuthenticationFailureHandler能够拦截)
            throw new BadCredentialsException(ResponseCode.A0005.getInfo());
        }
    }

    /**
     * 获取 头部信息 让合适的provider 来验证他
     */
    public void setDetails(HttpServletRequest request , PhoneCodeAuthenticationToken token){
        token.setDetails(this.authenticationDetailsSource.buildDetails(request));
    }

    public void setiAuthRepository(IAuthRepository iAuthRepository) {
        this.iAuthRepository = iAuthRepository;
    }
}
